<template>
  <div class="app-container">
    <n-scrollbar class="router-container" ref="scrollContainer" >
      <n-space vertical>
        <n-layout position="absolute" has-sider>
          <n-layout-sider
            bordered
            show-trigger
            collapse-mode="width"
            :collapsed-width="64"
            :width="240"
            :native-scrollbar="false"
            @scroll="handleScroll"
          >
            <n-affix>
              <div class="top-bar">
                <n-grid :x-gap="12" :cols="4">
                  <n-grid-item>
                    <n-dropdown trigger="click" :options="bookNames" @select="bookNameSelect">
                      <n-button text  
                      :style="{
                        marginTop: '10px',
                        marginLeft: buttonMarginLeft + 'px',
                        transition: 'margin-left 0.3s ease'
                      }">
                        <n-gradient-text text :size="titleSize " 
                          :style="{ transition: 'font-size 0.3s ease' }"
                          :gradient="{
                          from: 'rgb(85, 85, 85)',
                          to: 'rgb(170, 170, 170)',
                        }">
                          {{ bookName }}
                        </n-gradient-text>
                      </n-button>
                    </n-dropdown>
                  </n-grid-item>
                  <n-grid-item :offset="2">

                    <n-popover trigger="hover" placement="right-start">
                      <template #trigger>
                        <n-button text style="top: 13px;" @click.stop="addBookName()">
                            <n-icon :size="titleSize">
                              <Add />
                            </n-icon>
                        </n-button>
                      </template>
                      <span>添加分组</span>
                    </n-popover>
                  </n-grid-item>
                </n-grid>
              </div>
            </n-affix>

            <n-scrollbar :style="{maxHeight: lheight + 'px', height: lheight + 'px'}" @scroll="handleScroll">
              <n-list >
                <TreeList 
                ref="treeRef"
                v-model:nodes="options" 
                :handleLoadChildren="handleLoadChildren"
                v-model:selectedKey="selectedNodeKey"
                :select="onNodeSelected"
                :addNode="addNode"
                :deleteNode="deleteNode"
                :updateNode="updateNode"
                :updateNodeSort="updateNodeSort"
                />
              </n-list>
            </n-scrollbar>
          </n-layout-sider>
          <n-layout content-style="padding-left: 5px;" :native-scrollbar="false">
            <div v-if="selectedNodeKey.length > 0">
              <div v-if="selectedNode.type === 'moment'">

                <Editor
                  :id="selectedNode.key"
                  :key="selectedNode.key"
                  title=""
                  :content="searchText"
                  :type="type"
                  theme="vs"
                  @update:moment="(id:string, content:string, title:string, openType:string) => updateMomentContent(id, content, title, openType)"
                />
              </div>
              <div v-else>
                <n-affix>
                  <n-button dashed style="margin-top: 10px;" @click="newMomento">
                    新建
                  </n-button>
                </n-affix>
                <n-scrollbar :style="{maxHeight: cheight + 'px', height: cheight + 'px', paddingTop: '15px'}" >
                  <Content
                  v-model:nodes="contentLists"
                  @newText="newText"
                  @upTextLabel="upTextLable"
                   />
                </n-scrollbar>
              </div>
            </div>
          </n-layout>
        </n-layout>
      </n-space>
    </n-scrollbar>
  </div>






    <!-- 书名 -->
  <n-modal
    v-model:show="showBookNameList"
    title="书名"
    preset="card"
    draggable
    size="small"
    style=" width: 35%; max-height: 70%"
  >
    <div>
      <n-form ref="formRef" :model="bookNameModelRef" size="small" >
          <n-form-item path="title" label="标题">
            <n-input v-model:value="bookNameModelRef.title" @keydown.enter.prevent />
          </n-form-item>
          <n-form-item path="content" label="描述">
            <n-input v-model:value="bookNameModelRef.content" @keydown.enter.prevent />
          </n-form-item>

          <n-button @click="saveBookName">
            保存
          </n-button>
      </n-form>
    </div>
  </n-modal>
</template>

<script setup lang="ts">
  import { h, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
  import { NIcon, FormInst, NButton, TreeOption, useDialog, NInput, useMessage } from 'naive-ui'
  import { invoke } from '@tauri-apps/api/core';
  import TreeList, {type TreeExposed} from '../components/tree/TreeL.vue';
  import Content from '../components/content/Index.vue'
  import Editor from '../components/editor.vue'
  import {
    BookOutline as BookIcon,
    DocumentTextOutline,
    FolderOpenOutline,
    Add
  } from '@vicons/ionicons5'

  const treeRef = ref<TreeExposed | null>(null)
  const dialog = useDialog()
  const message = useMessage()
  // 在组件内部定义响应式变量
  const inputValue = ref('')
  interface TreeNodeData {
    key: string | number
    parentKey: string | number
    groupId: string | number
    type: string
    label?: string
    heading?: string
    content?: string
    children?: TreeNodeData[]
    pids?: Array<string | number>
  }

  const options = ref<TreeNodeData[]>([])

  const scrollContainer = ref()
  const eheight = ref("height: " + window.innerHeight * 0.5 + "px");
  const lheight = ref(window.innerHeight - 50)
  const cheight = ref(window.innerHeight - 60)
  const formRef = ref<FormInst | null>(null)
  const windowHeight = ref(window.innerHeight)

  //书名
  const showBookNameList = ref(false);
  const bookName = ref("");
  const bookId = ref();
  const bookNames = ref<any>([]);
  const bookNameSelectList = ref<any>([]);
  const bookNamesMenu = ref<any>([]);
  const bookNameList = ref<any>([])
  const bookNameType = ref("list")

  //内容
  const contentLists = ref<any>([])

  // 编辑器相关
  //let id = ref("");
  const type = ref("text");
  const searchText = ref('')

  const siderRef = ref<HTMLElement | null>(null)
  const siderScrollTarget = ref<HTMLElement | null>(null)

  interface BookName {
    id: string | null
    content: string | null
    use_time: number | null
    title: string | null
  }
  const bookNameModelRef = ref<BookName>({
    id: null,
    content: null,
    use_time: null,
    title: null,
  })

  // 选择书名
  function bookNameSelect(key: string | number) {
    if (key === 'addBookName') {
      showBookNameList.value = true;
      bookNameType.value = 'info'
    } else {
      for (const i in bookNamesMenu.value) {
        if (bookNamesMenu.value[i].key === String(key)) {
          bookName.value = bookNamesMenu.value[i].label
          bookId.value = String(key);
          break;
        }
      }
      getDirectoryByBookName(key);
    }
  }

  // 通过选择的书id查询目录
  async function getDirectoryByBookName(key: string | number) {
    options.value = [];
    if (key === 'allBook') {
      // 全部书名
      getBookList();
      options.value = bookNamesMenu.value;
    } else {
      options.value = await getDirectoryByBookId(key, "", null);
    }
  }

  // 父组件统一处理加载逻辑
  const handleLoadChildren = async (node: any) => {
    console.log("加载子节点", node);
    let list = await getDirectoryByBookId(node.type === 'book' ? node.key : node.groupId, node.type === 'book' ? "" : node.key, null);
    if (list) {
      let len = node.children.length
      node.children.push(...list);
      if (len != 0) {
        node.children.splice(0, len)
      }
    }
    node.isLoaded = true
  }

  const selectedNodeKey = ref<Array<string | number>>([]);
  const selectedNode = ref<any>(null);
  const onNodeSelected = async (node: any) => {
    console.log('父组件收到选中节点', node)
    selectedNode.value = node;
    selectedNodeKey.value = node.pids ? [...node.pids, node.key] : [node.key];
    if (node.type == 'book') {
      let list = await getDirectoryByBookId(node.key, "", null);
      bookId.value = String(node.key);
      contentLists.value = list;
    } else if (node.type == 'directory') {
      let list = await getDirectoryByBookId("", node.key, null);
      contentLists.value = list;
    } else if (node.type == 'moment') {
      let data:any = await invoke("get_info_by_id", { id: node.key });
      //console.log("=======", data);
      if (data.is_success) {
        searchText.value = data.data.note_content;
        node.content = data.data.note_content;
        if (data.data.open_type) {
          type.value = data.data.open_type;
        }
      }
    }
  }


  // 通过选择的书id查询目录
  async function getDirectoryByBookId(key: string | number, pid: string | number, isFolder: any) {  
    let groupTypes:any = await invoke("get_momento_tree", {bookId: (!key || key === "allBook" ? "" : key), pid: pid, isFolder: isFolder});
    //console.log("目录树", JSON.stringify(groupTypes));
    let list: any = [];
    if (groupTypes.is_success) {
      list = group_type_tree_to_tree(groupTypes.data);
    }
    //console.log("目录", list);
    return list;
  }

  function group_type_tree_to_tree(groupTypes:Array<any>) {
    let list: any = [];
    for (const i in groupTypes) {    
      list.push({
        label: groupTypes[i].title,
        icon: groupTypes[i].is_folder === 1 ? FolderOpenOutline : DocumentTextOutline,
        key: groupTypes[i].id,
        groupId: groupTypes[i].book_id,
        parentKey: groupTypes[i].pid,
        isLoaded: false,
        isFolder: groupTypes[i].is_folder,
        type: groupTypes[i].is_folder === 1 ? 'directory' : 'moment',
        content: groupTypes[i].content,
        heading: groupTypes[i].heading,
        children: groupTypes[i].children === null || groupTypes[i].children.length === 0 ? (groupTypes[i].is_folder === 1 ? [] : null): group_type_tree_to_tree(groupTypes[i].children),
        pids: groupTypes[i].pids.toString().split(',').map((pid: string) => pid.trim()),
      });
    }
    return list;
  }


  // 动态字体大小
  const titleSize = ref(34)
  const maxSize = 34
  const minSize = 15
  const buttonMarginLeft = ref(30)
  const router_container_top = ref(43);
  const maxOffset = 5
  function handleScroll(event: any) {
    const scrollTop = event.target.scrollTop
    const scaleRange = 400
    const ratio = Math.min(scrollTop / scaleRange, 1)
    const newSize = maxSize - (maxSize - minSize) * ratio
    titleSize.value = newSize
    buttonMarginLeft.value = 30 - (30 - maxOffset) * ratio
    router_container_top.value = 43 - (13) * ratio;
  }

  onMounted(async () => {
    getBookList();
    //await app.show();
    //await app.setFocus() // 确保窗口获得焦点
    window.addEventListener('resize', () => {windowHeight.value = window.innerHeight})
    nextTick(() => {
      if (scrollContainer.value) {
        //scrollContainer.value.addEventListener('scroll', handleScroll)
      }

      if (siderRef.value) {
        // 获取滚动容器
        siderScrollTarget.value = siderRef.value.querySelector('.n-layout-sider__scroll-container') as HTMLElement;
      }
    })
  })

  // 清理监听
  onUnmounted(() => {
    window.removeEventListener('resize', () => {windowHeight.value = window.innerHeight})
    //scrollContainer.value?.removeEventListener('scroll', handleScroll)
  })

  watch(windowHeight, (New: number, _Old: number) => {
    eheight.value = "height: " + New * 0.5 + "px";
    lheight.value = window.innerHeight - 50;
    cheight.value = window.innerHeight - 60;
  })

  async function addNode(node: any) {
    //console.log("====",node);
    if (node.type === 'book') {
      let data:any = await invoke("save_book_name", { title: node.label, content: node.label });
      //console.log("add -- ", data)
      if (data.is_success) {
        node.key = data.data
        node.groupId = node.key
        return node.key;
      } else {
        message.error(data.msg);
      }
    } else if (node.type === 'directory') {
      //console.log("================");
      let data:any = await invoke("add_momento", { pid: node.parentKey, bookId: node.groupId, noteContent: node.label, title: node.label, heading: node.label, isFolder: 1 });
      //console.log("add -- ", data)
      if (data.is_success) {
        node.key = data.data
        return node.key;
      } else {
        message.error(data.msg);
      }
    }
    return "-1";
  }

  function newText(node: any, key: string | number) {
    if (treeRef.value) {
      treeRef.value.addNode(node, key)
    }
  }

  function upTextLable(key: string | number, label: string) {
    if (treeRef.value) {
      treeRef.value.upNode(key, label)
    }
  }

  async function updateNode(node: any) {
    if (node.type === 'book') {
      let data:any = await invoke("update_book_name_info", { id: node.key, title: node.label });
      if (!data.is_success) {
        message.error(data.msg);
      }
    } else if (node.type === 'directory') {
      let data:any = await invoke("update_momento", { id: node.key, pid: node.parentKey, bookId:"", noteContent:node.label, title: node.label, heading: node.label, date: 0});
      if (!data.is_success) {
        message.error(data.msg);
      }
    } else if (node.type === 'moment') {
      let data:any = await invoke("update_momento", { id: node.key, pid: node.parentKey, bookId:"", noteContent:node.label, title: node.label, heading: node.label, date: 0});
      if (!data.is_success) {
        message.error(data.msg);
      }
    }
  }

  async function updateNodeSort(nodes: TreeOption[] | undefined, parentKey: string | number, book_id: string | number | undefined) {
    if (parentKey && parentKey === "root") {
      parentKey = "1";
    }
    if (nodes) {
      for (let i = 0; i < nodes.length; i++) {
        let node = nodes[i];
        if (node.type === 'book') {
          let data:any = await invoke("update_book_sort_info", { id: node.key, sort: i });
          if (data.is_success) {
            //之后在看是否需要更新到 tree中去
          }
        } else if (node.type === 'directory' || node.type === 'moment') {
          console.log("=============",parentKey ? parentKey : book_id);
          let data:any = await invoke("update_momento_sort", { id: node.key, sort: i, parentKey: (parentKey ? parentKey : book_id), bookId: book_id});
          if (data.is_success) {
            //之后在看是否需要更新到 tree中去
          }
        }
      }
    }
  }


  async function deleteNode(node: any) {
    if (node.type === 'book') {
      let groupTypes:any = await invoke("delete_book_name", { id: node.key.toString() });
      if (groupTypes.is_success) {
        getBookList();
        return true;
      } else {
        message.error(groupTypes.msg);
      }
    } else if (node.type === 'directory' || node.type === 'moment') {
      let groupTypes:any = await invoke("delete_momento", { id: node.key.toString() });
      if (groupTypes.is_success) {
        //之后在看是否需要更新到 tree中去
        contentLists.value = contentLists.value.filter((item: any) => item.key !== node.key);
        return true;
      } else {
        message.error(groupTypes.msg);
      }
    }
    return false;
  }

  async function saveBookName() {
    if (bookNameModelRef.value.id) {
      let data:any = await invoke("update_book_name_info", { id: bookNameModelRef.value.id, title: bookNameModelRef.value.title });
      if (data.is_success) {
        bookNameModelRef.value.id = null;
        bookNameModelRef.value.title = null;
        bookNameModelRef.value.content = null;
      }
    } else {
      let data:any = await invoke("save_book_name", { title: bookNameModelRef.value.title, content: bookNameModelRef.value.content });
      if (data.is_success) {
        bookNameModelRef.value.id = null;
        bookNameModelRef.value.title = null;
        bookNameModelRef.value.content = null;
      }
    }
    bookNameType.value = "list";
    getBookList();
    showBookNameList.value = false;
  }



  async function getBookList() {
    let data:any = await invoke("book_name_list");
    if (data.is_success) {
      bookNameList.value = [];
      bookNameList.value = data.data;
      bookNames.value = [];
      bookNameSelectList.value = [];
      bookNamesMenu.value = [];
      bookNames.value.push({
        label: "全部",
        key: "allBook",
      });
      bookName.value = "全部";
      bookId.value = "allBook";
      for (const i in bookNameList.value) {
        bookNamesMenu.value.push({
          label: bookNameList.value[i].title,
          icon: BookIcon,
          key: bookNameList.value[i].id,
          groupId: bookNameList.value[i].id,
          parentKey: "root",
          type: 'book',
          children: [],
        });
        bookNames.value.push({
          label: bookNameList.value[i].title,
          key: bookNameList.value[i].id,
        })
        bookNameSelectList.value.push({
          label: bookNameList.value[i].title,
          value: bookNameList.value[i].id,
        })
      }
      options.value = bookNamesMenu.value
      options.value.unshift({
          label: "默认",
          key: "1",
          groupId: "1",
          parentKey: "root",
          type: 'book',
          children: [],
        })
    }
  }


  function addBookName() {
    console.log("options. ", options.value)
    dialog.warning({
      title: '创建分组',
      closable: false,
      showIcon: false,
      content: () => h(NInput, {
        value: inputValue.value,
        onUpdateValue: (value: string) => {
          inputValue.value = value
        },
        placeholder: '请输入内容'
      }, {
        default: () => h(BookIcon)
      }),
      action: () => h(
        NButton,
        { text: true, 
          type: 'primary',
          onClick: async (_e: Event) => {
            dialog.destroyAll()
            let data = await addNode({
              "type":"book",
              "label":inputValue.value
            })
            options.value.splice(1, 0, {
                key: data,
                children: [],
                label:inputValue.value,
                parentKey: data,
                groupId: data,
                type: "book",
            })
          }
        },
        { default: () => "保存" }
      )
    })
  }


  async function newMomento() {
    let data:any = await invoke("add_momento", { 
      pid: selectedNode.value.key, 
      bookId: selectedNode.value.groupId, 
      noteContent: "", 
      title: "新建笔记", 
      heading: "", 
      isFolder: 0 });
    if (data.is_success) {
      let textNode = {
        key: data.data.toString(),
        children: [],
        parentKey: selectedNode.value.key,
        groupId: selectedNode.value.groupId,
        type: "moment",
        label: "新建笔记",
        pids: selectedNodeKey,
        isFolder: 0,
      };
      newText(textNode, selectedNode.value.key)
      contentLists.value.splice(0, 0, textNode)
    }
  }


  async function updateMomentContent(id: string, content: string, title: string, openType: string) {
    try {
      let data:any = await invoke("update_momento_content", { id: id, noteContent: content, title: title, openType: openType});
      if (data.is_success) {
      }
      console.log('后台已更新为:', content)
    } catch (e) {
      console.error(`invoke 调用失败`, e)
    }
  }
</script>

<style scoped>
.n-card {
  min-width: 200px;
  max-height: 600px;
}
.light-green {
  
  border: 1px dashed #ccc;
  background-color: rgba(243, 247, 243, 0.12);
}

.light-green.hovered {
  border: 2px dashed #925050;
}

.green {
  height: 108px;
  background-color: rgba(0, 128, 0, 0.24);
}


.add-momento {
  position: relative;
  width: 300px;
  height: 187px;
  border: 2px dashed #ccc;
  border-radius: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: border-color 0.3s;
}

.add-momento.hovered {
  border-color: #265abb; /* 当鼠标移入时边框颜色变为红色 */
}

.add-icon {
  position: absolute;
  height: 137px;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 36px;
}

.add-icon span {
  color: #333;
}


.floating-box {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 999;
  border-radius: 8px;
  padding: 10px;
  display: flex; 
  justify-content: flex-end; 
  align-items: center; 
  height: 40px;
}

.grid-container {
  display: grid;
  /* 每个单元格最多 30px 宽 */
  grid-template-columns: repeat(auto-fill, 35px);
  gap: 10px;
  margin-left: -10px;
}

.file-cell {
  /* 限定单元格盒子大小 */
  width: 40px;
  height: 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center; /* 内容居中 */
  cursor: pointer;
  font-size: 10px;
}


html, body {
  margin: 0;
  padding: 0;
  overflow: hidden;     /* 强制不出现页面滚动条 */
  height: 100%;
}

.app-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;     /* 绝对禁止外层滚动条 */
}

.router-container {
  left: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;     /* 只允许 router-view 区域滚动 */
}

.group-class {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  overflow-y: auto;     /* 只允许 router-view 区域滚动 */
}
</style>